package main

import (
	"bytes"
	"encoding/json"
	"howett.net/plist"
	"io/ioutil"
)

const ASSET_KIND_SOFTWARE_PACKAGE string = "software-package"
const ASSET_KIND_FULL_SIZE_IMAGE string = "full-size-image"
const ASSET_KIND_DISPLAY_IMAGE string = "display-image"
const ASSET_KIND_OTHERS string = "others"
const ASSET_KIND_PLIST string = "plist"

type PlistXMLDocument struct {
	Items []*PlistItem `plist:"items" json:"items"`
}

type PlistItem struct {
	Assets   []*PlistAsset  `plist:"assets" json:"assets"`
	MetaData *PlistMetaData `plist:"metadata" json:"meta_data"`
}

type PlistAsset struct {
	Kind  string `plist:"kind" json:"kind"`
	Shine bool   `plist:"needs-shine" json:"needs-shine"`
	URL   string `plist:"url" json:"url"`
}

type PlistMetaData struct {
	BundleIdentifier string `plist:"bundle-identifier" json:"bundle-identifier"`
	BundleVersion    string `plist:"bundle-version" json:"bundle-version"`
	Kind             string `plist:"kind" json:"kind"`
	Title            string `plist:"title" json:"title"`
	DownloadURL      string `plist:"-" json:"download-url"`
	PlistURL         string `plist:"-" json:"plist-url"`
	Creator          string `plist:"creator" json:"creator"`
	CreatedAt        string `plist:"created-at" json:"created-at"`
}

func NewPlistXMLDocument(filepath string) (doc *PlistXMLDocument, err error) {
	buf, err := ioutil.ReadFile(filepath)
	if err != nil {
		return nil, err
	}

	reader := bytes.NewReader(buf)

	decoder := plist.NewDecoder(reader)

	var data PlistXMLDocument
	err = decoder.Decode(&data)
	if err != nil {
		return nil, err
	}

	return &data, nil
}

func (doc *PlistXMLDocument) ToJSON() (string, error) {
	data, err := json.MarshalIndent(doc, "", "   ")
	if err != nil {
		log.Error(err)
		return "", err
	}

	return string(data), nil
}

func (doc *PlistXMLDocument) ToString() (string, error) {
	output, err := plist.MarshalIndent(doc, plist.XMLFormat, "    ")
	if err != nil {
		return "", err
	}

	return string(output), nil
}

func (doc *PlistXMLDocument) GetMate() *PlistMetaData {
	if len(doc.Items) > 0 {
		first := doc.Items[0]

		return first.MetaData
	}

	return &PlistMetaData{}
}

func (doc *PlistXMLDocument) GetAppName() string {
	return doc.GetMate().Title
}

func (doc *PlistXMLDocument) GetAppBundleName() string {
	return doc.GetMate().BundleIdentifier
}

func (doc *PlistXMLDocument) GetVersion() string {
	return doc.GetMate().BundleVersion
}

func (doc *PlistXMLDocument) GetAsset(kind string) *PlistAsset {
	if len(doc.Items) > 0 {
		first := doc.Items[0]

		if len(first.Assets) > 0 {
			for _, asset := range first.Assets {
				if asset.Kind == kind {
					return asset
				}
			}
		}

		asset := &PlistAsset{
			Kind:  kind,
			Shine: false,
			URL:   "",
		}

		first.Assets = append(first.Assets, asset)

		return asset
	}

	return nil
}
